package com.hmdp.utils;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.hmdp.dto.UserDTO;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static com.hmdp.utils.RedisConstants.LOGIN_USER_KEY;
import static com.hmdp.utils.RedisConstants.LOGIN_USER_TTL;

/**
 * 第一个拦截器
 * 拦截器作用：因为第二个某些请求路径不走，所以不会触发拦截器，那么用户的token无法刷新
 * 所以需要配置一个拦截所有的，刷新token时间
 * 这个拦截器只负责刷新token，校验不通过放下一个拦截器中
 */
public class RefreshTokenInterceptor implements HandlerInterceptor {

    private StringRedisTemplate stringRedisTemplate;

    /**
     *  由于当前类，spring不会加载，以此方式注入
     */
    public RefreshTokenInterceptor(StringRedisTemplate stringRedisTemplate){
        this.stringRedisTemplate = stringRedisTemplate;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //改为从redis中获取
        //获取到token,这个要看前端的参数，这个项目中前端的参数为authorization
        String token = request.getHeader("authorization");
        //获取到token后，判断是否为空，为空直接返回
        if(StringUtils.isBlank(token)){
            return true;
        }
        //如果存在，则从redis中取出值
        Map<Object, Object> userMap = stringRedisTemplate.opsForHash().entries(LOGIN_USER_KEY + token);
        //上面方法不会返回null，只会返回空
        if(userMap.isEmpty()){
            return true;
        }
        //将查询到的map转换为对象,第三个表示是否忽略转换中的错误，false不忽略
        UserDTO userDTO = BeanUtil.fillBeanWithMap(userMap, new UserDTO(), false);

        //存在保存
        UserHolder.saveUser(userDTO);

        //刷新有效期
        stringRedisTemplate.expire(LOGIN_USER_KEY+token,LOGIN_USER_TTL, TimeUnit.SECONDS);

        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        //移除
        UserHolder.removeUser();
    }
}
